/**
 * Provides the TicTacToe GameState example in the GQE library.
 *
 * @file src/GameState.cpp
 * @author Ryan Lindeman
 * @date 20110704 - Initial Release
 * @date 20110721 - Remove * from GetAsset() calls since it now returns TYPE&
 * @date 20110831 - Support new SFML2 snapshot changes
 * @date 20120421 - Use arial.ttf font since SFML 2 crashes on exit when using default font
 */
#include "GameState.hpp"
#include <GQE/Core/interfaces/IApp.hpp>

GameState::GameState(GQE::IApp& theApp) :
  GQE::IState("Game",theApp),
  mWinFont("resources/arial.ttf", GQE::AssetLoadNow),
  mPlayerImage("resources/Images/Player.png", GQE::AssetLoadNow),
  mScoreText(NULL),
  mRenderSystem(theApp),
  mMovementSystem(theApp),
  mShipPrototype("Ship",0),
  mPlayer(NULL),
  mBackgroundScrollSpeed(8)
{
  GQE::Int32 anIndex=0;
  std::string anFilename="";
  for(anIndex=0;anIndex<5;anIndex++)
  {
      std::stringstream anStream;
      anStream<<"resources/Images/Background"<<GQE::ConvertInt32(anIndex)<<".png";
      mBackground[anIndex]=GQE::ImageAsset(anStream.str(),GQE::AssetLoadNow);
  }
}

GameState::~GameState(void)
{
  delete mScoreText;
  mScoreText = NULL;
}

void GameState::DoInit(void)
{
  // First call our base class implementation
  IState::DoInit();

#if (SFML_VERSION_MAJOR < 2)
  mBackgroundSprite.SetImage(mBackground[0].GetAsset());
  mNextBackgroundSprite.SetImage(mBackground[1].GetAsset());
#else
  mBackgroundSprite.setTexture(mBackground[0].GetAsset());
  mNextBackgroundSprite.setTexture(mBackground[1].GetAsset());
  mNextBackgroundSprite.setPosition(sf::Vector2f(640,0));
#endif

#if (SFML_VERSION_MAJOR < 2)
  // Setup winner text color as White
  mScoreText = new(std::nothrow) sf::String("Score: 0", mWinFont.GetAsset(), 30.0f);
  mScoreText->SetColor(sf::Color::White);
#else
  // Setup winner text color as White
  mScoreText = new(std::nothrow) sf::Text("Score: 0", mWinFont.GetAsset(), 30);
  mScoreText->setColor(sf::Color::White);
#endif
  mShipPrototype.AddSystem(&mRenderSystem);
  mShipPrototype.AddSystem(&mMovementSystem);
  mShipPrototype.mProperties.Set<sf::Sprite>("Sprite",sf::Sprite(mPlayerImage.GetAsset()));
  mShipPrototype.mProperties.Set<sf::IntRect>("rSpriteRect",sf::IntRect(0,0,24,21));
  mShipPrototype.mProperties.Add<float>("fThrust",8.0f);
  // Call ReInit to reset the board
  ReInit();

  // Make sure our update loop is only called 30 times per second
  mApp.SetUpdateRate(30.0f);
}

void GameState::ReInit(void)
{
  //Reset the Level
  if(mPlayer!=NULL)
  {
    mPlayer->Destroy();
    mPlayer=NULL;
  }
  // Set Player entity
  mPlayer=mShipPrototype.MakeInstance();
  mPlayer->mProperties.Set<sf::Vector2f>("vPosition",sf::Vector2f(20,240));
}

void GameState::HandleEvents(sf::Event theEvent)
{
  // Exit program if Escape key is pressed
#if (SFML_VERSION_MAJOR < 2)
  if((theEvent.Type == sf::Event::KeyReleased) && (theEvent.Key.Code == sf::Key::Escape))
#else
  if((theEvent.type == sf::Event::KeyReleased) && (theEvent.key.code == sf::Keyboard::Escape))
#endif
  {
    // Signal the application to exit
    mApp.Quit(GQE::StatusAppOK);
  }

}

void GameState::UpdateFixed(void)
{
  //Move the player with arrow keys.
#if SFML_VERSION_MAJOR <2

#else
  sf::Vector2f anVelocity(0,0);
  float anThrust=mPlayer->mProperties.Get<float>("fThrust");
  if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
  {
    anVelocity.x-=anThrust;
  }
  if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
  {
    anVelocity.x+=anThrust;
  }
  if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
  {
    anVelocity.y-=anThrust;
  }
  if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
  {
    anVelocity.y+=anThrust;
  }
  mPlayer->mProperties.Set<sf::Vector2f>("vVelocity",anVelocity);
  mBackgroundSprite.setPosition(mBackgroundSprite.getPosition().x-mBackgroundScrollSpeed,0);
  mNextBackgroundSprite.setPosition(mNextBackgroundSprite.getPosition().x-mBackgroundScrollSpeed,0);
  //if the next background is in place.
  if(mNextBackgroundSprite.getPosition().x<=0)
  {
    //reset our backgrounds
    mBackgroundSprite.setPosition(0,0);
    mNextBackgroundSprite.setPosition(640,0);
    //Move to next background
    mCurrentBackground++;
    if(mCurrentBackground>=5)
    {
      mCurrentBackground=0;
    }
    mBackgroundSprite.setTexture(mBackground[mCurrentBackground].GetAsset());
    if(mCurrentBackground>=4)
    {
      mNextBackgroundSprite.setTexture(mBackground[0].GetAsset());
    }
    else
    {
      mNextBackgroundSprite.setTexture(mBackground[mCurrentBackground+1].GetAsset());
    }
  }
#endif
  mMovementSystem.UpdateFixed();

}

void GameState::UpdateVariable(float theElapsedTime)
{

}

void GameState::Draw(void)
{
#if (SFML_VERSION_MAJOR < 2)
  // Draw our Board sprite
  mApp.mWindow.Draw(mBackgroundSprite);
  mApp.mWindow.Draw(mNextBackgroundSprite);
#else
  // Draw our Board sprite
  mApp.mWindow.draw(mBackgroundSprite);
  mApp.mWindow.draw(mNextBackgroundSprite);
#endif
  mRenderSystem.Draw();

#if (SFML_VERSION_MAJOR < 2)
  // Draw winner text
  mApp.mWindow.Draw(*mScoreText);

#else
  // Draw winner text
  mApp.mWindow.draw(*mScoreText);
#endif
}

void GameState::HandleCleanup(void)
{
}

/**
 * Copyright (c) 2010-2012 Jacob Dix
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *ŜŘ
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
